#include <iostream>
#include "mylib.h"

using namespace std;

const int diem_dk = 24; // diem DK xet do
const double diem_dk_nn = 6.5;
unsigned sl_thi_sinh = 0; // so luong thi sinh
unsigned sl_do = 0; // so luong thi sinh do
unsigned sl_clc = 0;


void menu() {
	cout << "1. Nhap du lieu tu file TS.inp" << endl;
	cout << "2. Nhap du lieu tu ban phim" << endl;
	cout << "3. In danh sach thi sinh do va ghi ra file TS_Do.out" << endl;
	cout << "4. Thuc hien phuc khao" << endl;
	cout << "5. Bo xung diem Tieng anh" << endl;
	cout << "6. Bo xung diem Tieng anh tu file TS_DiemNgoaiNgu.inp" << endl;
	cout << "7. In danh sach lop CLC va ghi ra file TS_CLC.out" << endl;
	cout << "0. Ket thuc chuong trinh" << endl;
	cout << "Chon:";
}

void input( Ds_Ts head) {
	string ma, ten, que;
	int gt, ns, toan, ly, hoa;
	cout << "Ma thi sinh:";
	fflush(stdin);
	getline( cin, ma );
	while ( check_mats ( ma, head ) ) {
		cout << "Ma tren da ton tai.Yeu cau nhap lai:";
		fflush(stdin);
		getline(cin, ma );
	}
	while ( !check_cau_truc_mats( ma)){
		cout << "Cau truc ma thi sinh khong hop le. Yeu cau nhap lai:";
		fflush (stdin);
		getline ( cin, ma);
	}
	cout << "Ho ten:";
	fflush(stdin);
	getline( cin, ten );
	chuan_hoa ( ten );
	cout << "Gioi tinh ( Nam:1, Nu:0 ):";
	cin >> gt;
	cout << "Que quan:";
	fflush(stdin);
	getline( cin, que );
	cout << "Nam sinh:";
	cin >> ns;
	cout << "Diem toan:";
	cin >> toan;
	cout << "Diem ly:";
	cin >> ly;
	cout << "Diem hoa:";
	cin >> hoa;
	thi_sinh temp( ma, ten, gt, ns, que, toan, ly, hoa);
	Ds_Ts temp_head = head;
	while ( temp_head->get_next() != NULL) temp_head = temp_head->get_next();
	Ds_Ts temp1;
	temp1 = new thi_sinh;
	*temp1 = temp;
	(*temp_head).set_next( temp1 );
}

bool check_mats ( const string &str, Ds_Ts head ) {
	Ds_Ts temp = head;
	while ( (*temp).get_next() != NULL) {
		temp = (*temp).get_next();
		if ( str.compare( (*temp).get_ma_thi_sinh() )  == 0 ) return true;
	}
	return false;
}

void bo_cach_thua ( string &str ) {
	while ( str[0] == ' ') {
		str.erase ( 0, 1 );
	}
	int lenstr;
	lenstr = str.length();
	while ( str[ lenstr - 1 ] == ' ') {
		str.erase ( lenstr - 1, 1);
		lenstr = str.length();
	}
	string temp;
	for ( int i = 0; i < lenstr; i++) {
		if ( str[i] != ' ' || ( str[i] == ' ' && str[i + 1] != ' ')) {
			temp = temp + str[i];
		}
	}
	str = temp;
}


void chuan_hoa ( string &str ) {
	bo_cach_thua (str);
	int lenstr = str.length();
	if ( str[0] >= 'a' && str[0] <= 'z' ) str[0] = toupper( str[0] );
	for ( int i = 1; i < lenstr; i++) {
		if ( str[i] >= 'A' && str[i] <= 'Z' && str[i - 1] != ' ') str[i] = tolower ( str[i] );
		if ( str[i - 1] == ' ') str[i] = toupper ( str[i] );
	}
}

void swap ( Ds_Ts a, Ds_Ts b ) {
	thi_sinh temp;
	temp  = *a;
	*a = *b;
	*b = temp;
	thi_sinh *temp_next;
	temp_next = a->get_next();
	a->set_next ( b->get_next());
	b->set_next ( temp_next );
}

string get_ten ( const string &name) {
	int strlen = name.length();
	int t =  strlen;
	string ten;
	while ( t >= 0 && name[t] != ' ' ) t--;
	ten = name.substr ( t + 1, strlen - t );
	return ten;
}

string get_ho ( const string &name) {
	int strlen = name.length();
	int t =  strlen;
	string ho;
	while ( t >= 0 && name[t] != ' ' ) t--;
	ho = name.substr ( 0, t);
	return ho;
}

void sort_name ( Ds_Ts head ) {
	int so_thi_sinh = 0;
	Ds_Ts temp = head;
	while ( temp->get_next() != NULL ) {
		so_thi_sinh ++;
		temp = temp->get_next();
	}
	for ( int i = 0; i < so_thi_sinh; i++ ) {
		temp = head;
		for ( int k = 0; k < so_thi_sinh; k++ ){
			temp = head;
			temp = temp->get_next();
			while ( temp->get_next() != NULL ) {
				if ( get_ten( temp->get_ho_ten() ) == get_ten((temp->get_next() )->get_ho_ten() ) ) {
					if ( get_ho(temp->get_ho_ten() ) > get_ho((temp->get_next() )->get_ho_ten () ) )
						swap ( temp, temp->get_next() );
				} else if ( get_ten ( temp->get_ho_ten() ) > (get_ten ( (temp->get_next() )->get_ho_ten ()) ) )
					swap ( temp, temp->get_next() );
				temp = temp->get_next();
			}
		}
	}
	ofstream out_sap_xep ( "TS_SapXep.out", ios::out);
	if ( !out_sap_xep ) {
		cerr << "Khong the ghi file TS_SapXep.out" << endl;
		system ("pause");
		exit (1);
	}
	else {
		out_sap_xep << so_thi_sinh;
		out_sap_xep << fixed << setprecision(1);
		temp = head;
		while ( temp->get_next() != NULL ){
			temp = temp->get_next();
			out_sap_xep  << endl << temp->get_ma_thi_sinh() << " | " << temp->get_ho_ten() << " | ";
			if ( temp->get_gioi_tinh() == true ) out_sap_xep << "1 | ";
			else out_sap_xep << "0 | ";
			out_sap_xep << temp->get_nam_sinh() << " | " << temp->get_que_quan() << " | "
				<< temp->get_diem_toan() << " | " << temp->get_diem_ly() << " | " << temp->get_diem_hoa();
		}
		out_sap_xep.close();
	}
}
void sort_mark ( Ds_Ts head ) {
	int so_thi_sinh_do = 0;
	Ds_Ts temp = head;
	while ( temp->get_next() != NULL ) {
		if ( kt_do (temp->get_next()) ) so_thi_sinh_do ++;
		temp = temp->get_next();
	}
	for ( int i = 0; i < so_thi_sinh_do; i++ ) {
		temp = head;
		for ( int k = 0; k < so_thi_sinh_do; k++ ){
			temp = head;
			temp = temp->get_next();
			while ( temp->get_next() != NULL ) {
				temp = temp->get_next();
				if ( temp->get_tong_diem() < (temp->get_next())->get_tong_diem())
					swap ( temp, temp->get_next() );
				temp = temp->get_next();
			}
		}
	}
}
bool kt_do ( const Ds_Ts &ts) {
	if ( ts->get_tong_diem() >= diem_dk
		&& ts->get_diem_toan() > 0
		&& ts->get_diem_ly() > 0
		&& ts->get_diem_hoa() > 0 ) return true;
	return false;
}
void print_do ( Ds_Ts head) {
	sort_name ( head );
	ofstream out_do ( "TS_Do.out", ios::out);
	if ( !out_do ){
		cerr << "Khong the tao file TS_Do.out" << endl;
		system ("pause");
		exit (1);
	}
	else {
		Ds_Ts temp = head;
		while ( temp->get_next() != NULL) {
			temp = temp->get_next();
			if ( kt_do (temp) ) {
				sl_do ++;
				temp->print();
			}
			cout << endl;
		}
		out_do << sl_do;
		out_do << fixed << setprecision(1);
		temp = head;
		while ( temp->get_next() != NULL) {
			temp = temp->get_next();
			if ( kt_do (temp) ) {
				out_do << endl << temp->get_ma_thi_sinh() << " | " << temp->get_ho_ten() << " | ";
				if ( temp->get_gioi_tinh() == true ) out_do << "1 | ";
				else out_do << "0 | ";
				out_do << temp->get_nam_sinh() << " | " << temp->get_que_quan() << " | "
					<< temp->get_diem_toan() << " | " << temp->get_diem_ly() << " | " << temp->get_diem_hoa();
			}
		}
		out_do.close();
	}
}

void print_CLC ( Ds_Ts head ) {
	sort_mark ( head );
	Ds_Ts temp = head;
	while ( temp->get_next() != NULL && sl_clc <= 30) {
		temp = temp->get_next();
		if ( kt_do ( temp ) && temp->get_diem_tieng_anh() >= diem_dk_nn) {
			temp->print();
			sl_clc ++;
			cout << endl;
		}
	}
	ofstream out_clc ( "TS_CLC.out", ios::out);
	if ( !out_clc ) {
		cerr << "Khong the tao file TS_CLC.out" << endl;
		system ("pause");
		exit (1);
	}
	else {
		out_clc << sl_clc;
		out_clc << fixed << setprecision(1);
		temp = head;
		while ( temp->get_next() != NULL && sl_clc <= 30) {
			temp = temp->get_next();
			if ( kt_do ( temp ) && temp->get_diem_tieng_anh() >= diem_dk_nn) {
				out_clc << endl << temp->get_ma_thi_sinh() << " | " << temp->get_ho_ten() << " | ";
				if ( temp->get_gioi_tinh() == true ) out_clc << "1 | ";
				else out_clc << "0 | ";
				out_clc << temp->get_nam_sinh() << " | " << temp->get_que_quan() << " | "
					<< temp->get_diem_toan() << " | " << temp->get_diem_ly() << " | " << temp->get_diem_hoa() << " | "
					<< temp->get_diem_tieng_anh();
			}
		}
	}
	out_clc.close();
}

void bo_xung_TA ( Ds_Ts head) {
	sort_name ( head );
	Ds_Ts temp = head;
	double diem_TA;
	while ( temp->get_next() != NULL ) {
		temp = temp->get_next();
		if ( kt_do ( temp )) {
			cout << temp->get_ma_thi_sinh() << ":";
			cin >> diem_TA;
			while ( diem_TA > 10 || diem_TA < 0){
				cout << "Diem tieng anh khong hop le. Yeu cau nhap lai:";
				cin >> diem_TA;
			}
			temp->set_diem_tieng_anh( diem_TA);
		}
	}
}

void phuc_khao ( const string &maTS, Ds_Ts head) {
	if ( check_mats(maTS, head) == false ) cout << "Ma thi sinh khong ton tai!" << endl;
	else {
		Ds_Ts temp = head;
		while ( (*temp).get_next() != NULL) {
			temp = (*temp).get_next();
			if ( maTS.compare( (*temp).get_ma_thi_sinh() )  == 0 ) break;
		}
		cout << "Thuc hien thay doi diem thi sinh " << maTS << endl;
		int diem;
		cout << "Diem toan:";
		cin >> diem;
		temp->set_diem_toan ( diem );
		cout << "Diem ly:";
		cin >> diem;
		temp->set_diem_ly ( diem );
		cout << "Diem hoa:";
		cin >> diem;
		temp->set_diem_hoa ( diem );
		sort_name (head);
	}
}

bool phan_cach ( const char &a) {
	if ( a == '|' || a == ';' || a == ':' || a == '\n') return true;
	return false;
}

void input_from_file ( Ds_Ts head) {
	string a;
	string sl;
	double toan, ly, hoa;
	int gt, ns, sl_ts;
	sl_ts = 0;
	ifstream open ( "TS.inp", ios::in );
	if ( !open ) {
		cerr << "Khong the mo file";
		system ("pause");
		exit (1);
	} else {
		cout << "Mo file thanh cong" << endl;
		open >> sl_thi_sinh;
		if ( sl_thi_sinh > 10000) {
			cerr << "So luong thi sinh phai nho hon 10000" << endl;
			system ("pause");
			exit (1);
		}
	}
	//---------------------------------------------
	string *arr;
	arr = new string [ 8 ];
	getline ( open, a );
	for (int ts = 0; !open.eof() ; ts ++) {
		getline ( open, a );
		if ( a.empty() ) continue;
		for ( int i = 0; i < 8; i ++) arr[i].clear();
		int k, t;
		t = k = 0;
		for ( int i = 0; i < 8; i ++) {
			t = k;
			while ( a[k] != '|' && a[k] != ';' && a[k] != ':' && k < a.length() - 1 ) k++;
			if ( k == a.length() - 1 ) arr[i] = a.substr ( t, k - t + 1);
			else arr[i] = a.substr ( t, k - t);
			if ( k != a.length() - 1 ){
				k++;
				while ( a[k] == '|' || a[k] == ';' || a[k] == ':') k++;
			}
		}
		chuan_hoa( arr[1]);
		for ( int i = 0; i < 8; i++) bo_cach_thua ( arr[i]);
		//----------------------------------
		{
			char *c;
			c = new char [ arr[2].length () + 1];
			c [ arr[2].length () ] = '\0';
			memcpy ( c, arr[2].c_str(), arr[2].length() );
			gt = atoi (c);
		}

		//----------------------------------
		{
			char *c;
			c = new char [ arr[3].length () + 1];
			c [ arr[3].length () ] = '\0';
			memcpy ( c, arr[3].c_str(), arr[3].length() );
			ns = atoi (c);
		}
		//--------------------------
		{
			char *c;
			c = new char [ arr[5].length () + 1];
			c [ arr[5].length () ] = '\0';
			memcpy ( c, arr[5].c_str(), arr[5].length() );
			toan = strtod (c, NULL);
		}
		//----------------------------------
		{
			char *c;
			c = new char [ arr[6].length () + 1];
			c [ arr[6].length () ] = '\0';
			memcpy ( c, arr[6].c_str(), arr[6].length() );
			ly = strtod (c,NULL);
		}
		//-----------------------------------
		{
			char *c;
			c = new char [ arr[7].length () + 1];
			c [ arr[7].length () ] = '\0';
			memcpy ( c, arr[7].c_str(), arr[7].length() );
			hoa = strtod (c,NULL);
		}
		//----------------------------------
		if ( check_mats( arr[0], head) || !check_cau_truc_mats( arr[0]) ){
			cerr << "Ma thi sinh trong file khong hop le hoac bi trung. Yeu cau kiem tra lai" << endl;
			system ("pause");
			exit (1);
		}
		thi_sinh temp( arr[0], arr[1], gt, ns, arr[4], toan, ly, hoa);
		Ds_Ts temp_head = head;
		while ( temp_head->get_next() != NULL) temp_head = temp_head->get_next();
		Ds_Ts temp1;
		temp1 = new thi_sinh;
		*temp1 = temp;
		(*temp_head).set_next( temp1 );
		sl_ts++;
	}
	open.close();
	if ( sl_ts != sl_thi_sinh){
		cerr << "So luong thi sinh thuc te khong dung!" << endl;
		system ("pause");
		exit (1);
	}
	cout << "Nhap du lieu tu file thanh cong" << endl;
}

bool check_cau_truc_mats ( string &mats){
	bo_cach_thua ( mats );
	if ( mats.length() != 8) return false;
	for ( int i = 0; i < 4; i++) if ( !isalpha( mats[i])) return false;
	for ( int i = 4; i < 8; i++) if ( !isdigit( mats[i])) return false;
	return true;
}

void input_ngoai_ngu ( Ds_Ts head){
	ifstream open_file ( "TS_DiemNgoaiNgu.inp", ios::in);
	int sl;
	double ta;
	Ds_Ts temp;
	if ( !open_file ){
		cerr << "Khong the mo file";
		system ("pause");
		exit (1);
	}
	else {
		cout << "Mo file thanh cong" << endl;
		open_file >> sl;
		string *arr, a;
		arr = new string [2];
		getline ( open_file, a);
		int t, k;
		t = k = 0;
		for ( int s = 0; s < sl;){
			getline ( open_file, a);
			if ( a.empty() ) continue;
			for ( int i = 0; i < 2; i ++) arr[i].clear();
			for ( int i = 0; i < 2; i ++) {
				t = k;
				while ( a[k] != '|' && a[k] != ';' && a[k] != ':' && k < a.length() - 1 ) k++;
				if ( k == a.length() - 1 ) arr[i] = a.substr ( t, k - t + 1);
				else arr[i] = a.substr ( t, k - t);
				if ( k != a.length() - 1 ){
					k++;
					while ( a[k] == '|' || a[k] == ';' || a[k] == ':') k++;
				}
			}
			bo_cach_thua (arr[0]);
			bo_cach_thua (arr[1]);
			{
				char *c;
				c = new char [ arr[1].length () + 1];
				c [ arr[1].length () ] = '\0';
				memcpy ( c, arr[1].c_str(), arr[1].length() );
				ta = strtod (c, NULL);
			}
			if ( check_mats( arr[0], head)) {
				temp = head;
				while ( (*temp).get_next() != NULL) {
					temp = (*temp).get_next();
					if ( arr[0].compare( (*temp).get_ma_thi_sinh() )  == 0 ) break;
				}
				temp->set_diem_tieng_anh ( ta);
			}
			s ++;
		}
		cout << "Bo xung diem thanh cong" << endl;
	}
	open_file.close();
}